package com.csea.app.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.csea.app.model.vo.auth.LoginReqVO;
import com.csea.app.model.vo.auth.LoginRspVO;
import com.csea.app.model.vo.auth.RegisterReqVO;
import com.csea.app.model.vo.repository.RepositoryCreateReqVO;
import com.csea.app.model.vo.user.PasswordUpdateReqVO;
import com.csea.app.model.vo.user.UserBaseInfoUpdateReqVO;
import com.csea.app.model.vo.user.UserInfoRspVO;
import com.csea.app.service.UserAccountService;
import com.csea.app.service.UserRepositoryService;
import com.csea.common.domain.dos.UserAccountDo;
import com.csea.common.domain.mapper.UserAccountMapper;
import com.csea.common.enums.ResponseCodeEnum;
import com.csea.common.exception.BizException;
import com.csea.common.utils.Response;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
@Slf4j
public class UserAccountServiceImpl implements UserAccountService {

    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    @Autowired
    private UserAccountMapper userAccountMapper;
    @Autowired
    private UserRepositoryService userRepositoryService;

    /**
     * 登录
     *
     * @param loginReqVO 登录信息
     * @return 登录结果
     */
    @Override
    public Response<LoginRspVO> login(LoginReqVO loginReqVO) {
        String username = loginReqVO.getUsername();
        String password = loginReqVO.getPassword();

        UserAccountDo user = userAccountMapper.selectByUsername(username);
        if (user == null || !passwordEncoder.matches(password, user.getPasswordHash())) {
            return Response.fail("用户名或密码错误");
        }
        StpUtil.login(user.getUserId());

        LoginRspVO loginRspVO = LoginRspVO.builder()
                .userId(user.getUserId())
                .username(user.getUsername())
                .email(user.getEmail())
                .phone(user.getPhone())
                .wechat(user.getWechat())
                .qq(user.getQq())
                .registerTime(user.getRegisterTime().toString())
                .wordCount(user.getWordCount())
                .masteredCount(user.getMasteredCount())
                .studyTime(user.getStudyTime())
                .token(StpUtil.getTokenValue())
                .name(user.getName())
                .gender(user.getGender())
                .age(user.getAge())
                .build();

        return Response.success(loginRspVO);
    }

    /**
     * 注册
     *
     * @param registerReqVO 注册信息
     * @return 注册结果
     */
    @Override
    public Response<String> register(RegisterReqVO registerReqVO) {
        // 先检查是否退出登录状态
        if (StpUtil.isLogin()) {
            return Response.fail(ResponseCodeEnum.USER_ALREADY_LOGGED_IN);
        }

        String username = registerReqVO.getUsername();

        // 检查用户名是否已存在
        if (userAccountMapper.selectByUsername(username) != null) {
            return Response.fail(ResponseCodeEnum.USERNAME_EXIST_ERROR);
        }

        // 创建用户对象
        UserAccountDo user = UserAccountDo.builder()
                .username(username)
                .passwordHash(passwordEncoder.encode(registerReqVO.getPassword()))
                .registerTime(new Date())
                .status((byte) 1) // 账户状态：1-正常
                .name("默认用户_" + username)
                .build();

        // 插入数据库
        userAccountMapper.insert(user);

        // 创建默认仓库
        RepositoryCreateReqVO repoReq = new RepositoryCreateReqVO();
        repoReq.setRepositoryName("默认仓库");
        repoReq.setRepositoryType("IDIOM");
        repoReq.setDescription("默认仓库");
        repoReq.setUserId(user.getUserId());
        userRepositoryService.createRepository(repoReq);

        return Response.success("注册成功，请登录。");
    }

    /**
     * 登出
     */
    @Override
    public Response<String> logout() {
        StpUtil.logout();
        return Response.success();
    }

    /**
     * 获取当前用户信息
     *
     * @return 当前用户信息
     */
    @Override
    public Response<UserInfoRspVO> getCurrentUserInfo() {
        int userId = StpUtil.getLoginIdAsInt();
        UserAccountDo user = userAccountMapper.selectById(userId);

        if (user == null) {
            return Response.fail("用户不存在");
        }
        return getUserInfoRspVOResponse(user);
    }


    /**
     * 更新用户基本信息
     *
     * @param reqVO 用户信息
     * @return 更新结果
     */
    @Override
    @Transactional
    public Response<UserInfoRspVO> updateUserBaseInfo(UserBaseInfoUpdateReqVO reqVO) {
        Integer userId = StpUtil.getLoginIdAsInt();
        UserAccountDo userDo = new UserAccountDo();
        userDo.setUserId(userId);

        if (reqVO.getName() != null) userDo.setName(reqVO.getName());
        if (reqVO.getGender() != null) userDo.setGender(reqVO.getGender());
        if (reqVO.getAge() != null) userDo.setAge(reqVO.getAge());
        if (reqVO.getEmail() != null) userDo.setEmail(reqVO.getEmail());
        if (reqVO.getPhone() != null) userDo.setPhone(reqVO.getPhone());
        if (reqVO.getWechat() != null) userDo.setWechat(reqVO.getWechat());
        if (reqVO.getQq() != null) userDo.setQq(reqVO.getQq());

        userAccountMapper.updateById(userDo);
        userDo = userAccountMapper.selectById(userId);
        return getUserInfoRspVOResponse(userDo);
    }


    /**
     * 更新用户密码
     *
     * @param reqVO 用户信息
     * @return 更新结果
     */
    @Override
    @Transactional
    public Response<String> updatePassword(PasswordUpdateReqVO reqVO) {
        Integer userId = StpUtil.getLoginIdAsInt();
        UserAccountDo user = userAccountMapper.selectById(userId);

        if (!passwordEncoder.matches(reqVO.getOldPassword(), user.getPasswordHash())) {
            throw new BizException(ResponseCodeEnum.OLD_PASSWORD_MISMATCH);
        }

        UserAccountDo updateDo = new UserAccountDo();
        updateDo.setUserId(userId);
        updateDo.setPasswordHash(passwordEncoder.encode(reqVO.getNewPassword()));
        userAccountMapper.updateById(updateDo);
        return Response.success("用户密码更新成功");
    }


    @NotNull
    private Response<UserInfoRspVO> getUserInfoRspVOResponse(UserAccountDo userDo) {
        UserInfoRspVO userInfoRspVO = UserInfoRspVO.builder()
                .userId(userDo.getUserId())
                .username(userDo.getUsername())
                .email(userDo.getEmail())
                .phone(userDo.getPhone())
                .wechat(userDo.getWechat())
                .qq(userDo.getQq())
                .registerTime(userDo.getRegisterTime().toString())
                .wordCount(userDo.getWordCount())
                .masteredCount(userDo.getMasteredCount())
                .studyTime(userDo.getStudyTime())
                .name(userDo.getName())
                .gender(userDo.getGender())
                .age(userDo.getAge())
                .build();

        return Response.success(userInfoRspVO);
    }
}
